home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / drivers / wecleman.c < prev    next >
C/C++ Source or Header  |  2000-05-06  |  53KB  |  1,769 lines

  1. /***************************************************************************
  2.                         WEC Le Mans 24  &   Hot Chase
  3.  
  4.                           (C)   1986 & 1988 Konami
  5.  
  6.                     driver by    Luca Elia (eliavit@unina.it)
  7.  
  8.  
  9. ----------------------------------------------------------------------
  10. Hardware                Main     Sub        Sound    Sound Chips
  11. ----------------------------------------------------------------------
  12. [WEC Le Mans 24]        68000    68000    Z-80    YM2151 YM3012 1x007232
  13.  
  14. [Hot Chase]                68000    68000    68B09E                  3x007232
  15.  
  16.  [CPU PCB GX763 350861B]
  17.                          007641    007770    3x007232    051550
  18.  
  19.  [VID PCB GX763 350860A AI AM-1]
  20.                          007634    007635    3x051316    007558    007557
  21. ----------------------------------------------------------------------
  22.  
  23.  
  24. ----------------------------------------------------------------
  25. Main CPU                [WEC Le Mans 24]        [Hot Chase]
  26. ----------------------------------------------------------------
  27. ROM                R        000000-03ffff            <
  28. Work RAM        RW        040000-043fff            040000-063fff*
  29. ?                RW        060000-060007            -
  30. Blitter             W        080000-080011            <
  31. Page RAM        RW        100000-103fff            -
  32. Text RAM        RW        108000-108fff            -
  33. Palette RAM        RW        110000-110fff            110000-111fff**
  34. Shared RAM        RW        124000-127fff            120000-123fff
  35. Sprites RAM        RW        130000-130fff            <
  36. Input Ports        RW        1400xx-1400xx            <
  37. Background        RW        -                        100000-100fff
  38. Background Ctrl     W        -                        101000-10101f
  39. Foreground        RW        -                        102000-102fff
  40. Foreground Ctrl     W        -                        103000-10301f
  41.  
  42. * weird                    ** only half used
  43.  
  44. ----------------------------------------------------------------
  45. Sub CPU                    [WEC Le Mans 24]        [Hot Chase]
  46. ----------------------------------------------------------------
  47.  
  48. ROM                R        000000-00ffff            000000-01ffff
  49. Work RAM        RW        -                        060000-060fff
  50. Road RAM        RW        060000-060fff            020000-020fff
  51. Shared RAM        RW        070000-073fff            040000-043fff
  52.  
  53.  
  54. ---------------------------------------------------------------------------
  55.                                 Game code
  56.                             [WEC Le Mans 24]
  57. ---------------------------------------------------------------------------
  58.  
  59.                     Interesting locations (main cpu)
  60.                     --------------------------------
  61.  
  62. There's some 68000 assembly code in ASCII around d88 :-)
  63.  
  64. 040000+
  65. 7-9                *** hi score/10 (BCD 3 bytes) ***
  66. b-d                *** score/10 (BCD 3 bytes) ***
  67. 1a,127806        <- 140011.b
  68. 1b,127807        <- 140013.b
  69. 1c,127808        <- 140013.b
  70. 1d,127809        <- 140015.b
  71. 1e,12780a        <- 140017.b
  72. 1f                <- 140013.b
  73. 30                *** credits ***
  74. 3a,3b,3c,3d        <-140021.b
  75. 3a = accelerator   3b = ??   3c = steering   3d = table
  76.  
  77. d2.w            -> 108f24 fg y scroll
  78. 112.w            -> 108f26 bg y scroll
  79.  
  80. 16c                influences 140031.b
  81. 174                screen address
  82. 180                input port selection (->140003.b ->140021.b)
  83. 181                ->140005.b
  84. 185                bit 7 high -> must copy sprite data to 130000
  85. 1dc+(1da).w        ->140001.b
  86.  
  87. 40a.w,c.w        *** time (BCD) ***
  88. 411                EF if brake, 0 otherwise
  89. 416                ?
  90. 419                gear: 0=lo,1=hi
  91. 41e.w            speed related ->127880
  92. 424.w            speed BCD
  93. 43c.w            accel?
  94. 440.w            level?
  95.  
  96. 806.w            scrollx related
  97. 80e.w            scrolly related
  98.  
  99. c08.b            routine select: 1>1e1a4    2>1e1ec    3>1e19e    other>1e288 (map screen)
  100.  
  101. 117a.b            selected letter when entering name in hi-scores
  102. 117e.w            cycling color in hi-scores
  103.  
  104. 12c0.w            ?time,pos,len related?
  105. 12c2.w
  106. 12c4.w
  107. 12c6.w
  108.  
  109. 1400-1bff        color data (0000-1023 chars)
  110. 1c00-23ff        color data (1024-2047 sprites?)
  111.  
  112. 2400            Sprite data: 40 entries x  4 bytes =  100
  113. 2800            Sprite data: 40 entries x 40 bytes = 1000
  114. 3800            Sprite data: 40 entries x 10 bytes =  400
  115.  
  116.                     Interesting routines (main cpu)
  117.                     -------------------------------
  118.  
  119. 804                mem test
  120. 818                end mem test (cksums at 100, addresses at A90)
  121. 82c                other cpu test
  122. a0c                rom test
  123. c1a                prints string (a1)
  124. 1028            end test
  125. 204c            print 4*3 box of chars to a1, made up from 2 2*6 (a0)=0xLR (Left,Righ index)
  126. 4e62            raws in the fourth page of chars
  127. 6020            test screen (print)
  128. 60d6            test screen
  129. 62c4            motor test?
  130. 6640            print input port values ( 6698 = scr_disp.w,ip.b,bit.b[+/-] )
  131.  
  132. 819c            prepares sprite data
  133. 8526            blitter: 42400->130000
  134. 800c            8580    sprites setup on map screen
  135.  
  136. 1833a            cycle cols on hi-scores
  137. 18514            hiscores: main loop
  138. 185e8            hiscores: wheel selects letter
  139.  
  140. TRAP#0            prints string: A0-> addr.l, attr.w, (char.b)*, 0
  141.  
  142. IRQs            1,3,6]    602
  143.                 2,7]    1008->12dc    ORI.W    #$2700,(A7) RTE
  144.                 4]    1004->124c
  145.                 5]    106c->1222    calls sequence: $3d24 $1984 $28ca $36d2 $3e78
  146.  
  147.  
  148.  
  149.  
  150.                     Interesting locations (sub cpu)
  151.                     -------------------------------
  152.  
  153.                     Interesting routines (sub cpu)
  154.                     ------------------------------
  155.  
  156. 1028    'wait for command' loop.
  157. 1138    lev4 irq
  158. 1192    copies E0*4 bytes: (a1)+ -> (a0)+
  159.  
  160.  
  161.  
  162.  
  163.  
  164. ---------------------------------------------------------------------------
  165.                                  Game code
  166.                                 [Hot Chase]
  167. ---------------------------------------------------------------------------
  168.  
  169. This game has been probably coded by the same programmers of WEC Le Mans 24
  170. It shares some routines and there is the (hidden?) string "WEC 2" somewhere
  171.  
  172.                             Main CPU        Sub CPU
  173.  
  174. Interrupts:        1, 7]         FFFFFFFF        FFFFFFFF
  175.                 2,3,4,5,6]    221c            1288
  176.  
  177. Self Test:
  178.  0] pause,120002==55,pause,120002==AA,pause,120002==CC, (on error set bit d7.0)
  179.  6] 60000-63fff(d7.1),40000-41fff(d7.2)
  180.  8] 40000/2<-chksum 0-20000(e/o);40004/6<-chksum 20000-2ffff(e/o) (d7.3456)
  181.  9] chksums from sub cpu: even->40004    odd->(40006)    (d7.78)
  182.  A] 110000-111fff(even)(d7.9),102000-102fff(odd)(d7.a)
  183.  C] 100000-100fff(odd)(d7.b),pause,pause,pause
  184. 10] 120004==0(d7.c),120006==0(d7.d),130000-1307ff(first $A of every $10 bytes only)(d7.e),pause
  185. 14] 102000<-hw screen+(d7==0)? jmp 1934/1000
  186. 15] 195c start of game
  187.  
  188.  
  189.                     Interesting locations (main cpu)
  190.                     --------------------------------
  191.  
  192. 60024.b            <- !140017.b (DSW 1 - coinage)
  193. 60025.b            <- !140015.b (DSW 2 - options)
  194. 6102c.w            *** time ***
  195.  
  196.                     Interesting routines (main cpu)
  197.                     -------------------------------
  198.  
  199. 18d2            (d7.d6)?print BAD/OK to (a5)+, jmp(D0)
  200. 1d58            print d2.w to (a4)+, jmp(a6)
  201. 580c            writes at 60000
  202. 61fc            print test strings
  203. 18cbe            print "game over"
  204.  
  205.  
  206.  
  207.  
  208. ---------------------------------------------------------------------------
  209.                                    Issues
  210.                               [WEC Le Mans 24]
  211. ---------------------------------------------------------------------------
  212.  
  213. - Wrong colours (only the text layer is ok at the moment. Note that the top
  214.   half of colours is written by the blitter, 16 colours a time, the bottom
  215.   half by the cpu, 8 colours a time)
  216. - The parallactic scrolling is sometimes wrong
  217.  
  218. ---------------------------------------------------------------------------
  219.                                    Issues
  220.                                 [Hot Chase]
  221. ---------------------------------------------------------------------------
  222.  
  223. - Samples pitch is too low
  224. - No zoom and rotation of the layers
  225.  
  226. ---------------------------------------------------------------------------
  227.                                Common Issues
  228. ---------------------------------------------------------------------------
  229.  
  230. - One ROM unused (32K in hotchase, 16K in wecleman)
  231. - Incomplete DSWs
  232. - No shadow sprites
  233. - Sprite ram is not cleared by the game and no sprite list end-marker
  234.   is written. We cope with that with an hack in the Blitter but there
  235.   must be a register to do the trick
  236.  
  237.  
  238. ***************************************************************************/
  239.  
  240. #include "driver.h"
  241. #include "vidhrdw/generic.h"
  242. #include "vidhrdw/konamiic.h"
  243. #include "cpu/m6809/m6809.h"
  244.  
  245. /* Variables only used here: */
  246.  
  247. static unsigned char *sharedram, *blitter_regs;
  248. static int multiply_reg[2];
  249.  
  250.  
  251.  
  252. /* Variables that vidhrdw has acces to: */
  253.  
  254. int wecleman_selected_ip, wecleman_irqctrl;
  255.  
  256.  
  257. /* Variables defined in vidhrdw: */
  258.  
  259. extern unsigned char *wecleman_pageram, *wecleman_txtram, *wecleman_roadram, *wecleman_unknown;
  260. extern size_t wecleman_roadram_size;
  261. extern int wecleman_bgpage[4], wecleman_fgpage[4], *wecleman_gfx_bank;
  262.  
  263.  
  264. /* Functions defined in vidhrdw: */
  265.  
  266. WRITE_HANDLER( paletteram_SBGRBBBBGGGGRRRR_word_w );
  267.  
  268. READ_HANDLER( wecleman_pageram_r );
  269. WRITE_HANDLER( wecleman_pageram_w );
  270. READ_HANDLER( wecleman_txtram_r );
  271. WRITE_HANDLER( wecleman_txtram_w );
  272. void wecleman_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
  273. int  wecleman_vh_start(void);
  274.  
  275. void hotchase_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
  276. int  hotchase_vh_start(void);
  277. void hotchase_vh_stop(void);
  278.  
  279.  
  280.  
  281. /* This macro is used to decipher the gfx ROMs */
  282.  
  283. #define BITSWAP(_from,_len,_14,_13,_12,_11,_10,_f,_e,_d,_c,_b,_a,_9,_8,_7,_6,_5,_4,_3,_2,_1,_0)\
  284. {    unsigned char *buffer; \
  285.     unsigned char *src = _from; \
  286.     if ((buffer = malloc(_len))) \
  287.     { \
  288.         for (i = 0 ; i <= _len ; i++) \
  289.             buffer[i] = \
  290.              src[(((i & (1 << _0))?(1<<0x0):0) + \
  291.                  ((i & (1 << _1))?(1<<0x1):0) + \
  292.                  ((i & (1 << _2))?(1<<0x2):0) + \
  293.                  ((i & (1 << _3))?(1<<0x3):0) + \
  294.                  ((i & (1 << _4))?(1<<0x4):0) + \
  295.                  ((i & (1 << _5))?(1<<0x5):0) + \
  296.                  ((i & (1 << _6))?(1<<0x6):0) + \
  297.                  ((i & (1 << _7))?(1<<0x7):0) + \
  298.                  ((i & (1 << _8))?(1<<0x8):0) + \
  299.                  ((i & (1 << _9))?(1<<0x9):0) + \
  300.                  ((i & (1 << _a))?(1<<0xa):0) + \
  301.                  ((i & (1 << _b))?(1<<0xb):0) + \
  302.                  ((i & (1 << _c))?(1<<0xc):0) + \
  303.                  ((i & (1 << _d))?(1<<0xd):0) + \
  304.                  ((i & (1 << _e))?(1<<0xe):0) + \
  305.                  ((i & (1 << _f))?(1<<0xf):0) + \
  306.                  ((i & (1 << _10))?(1<<0x10):0) + \
  307.                  ((i & (1 << _11))?(1<<0x11):0) + \
  308.                  ((i & (1 << _12))?(1<<0x12):0) + \
  309.                  ((i & (1 << _13))?(1<<0x13):0) + \
  310.                  ((i & (1 << _14))?(1<<0x14):0))]; \
  311.         memcpy(src, buffer, _len); \
  312.         free(buffer); \
  313.     } \
  314. }
  315.  
  316.  
  317.  
  318. /***************************************************************************
  319.                             Common routines
  320. ***************************************************************************/
  321.  
  322.  
  323. /* 140005.b (WEC Le Mans 24 Schematics)
  324.  
  325.  COMMAND
  326.  ___|____
  327. |   CK  8|--/            7
  328. | LS273 7| TV-KILL        6
  329. |       6| SCR-VCNT        5
  330. |       5| SCR-HCNT        4
  331. |   5H  4| SOUND-RST    3
  332. |       3| SOUND-ON        2
  333. |       2| NSUBRST        1
  334. |       1| SUBINT        0
  335. |__CLR___|
  336.     |
  337.   NEXRES
  338.  
  339.  Schems: SUBRESET does a RST+HALT
  340.          Sub CPU IRQ 4 generated by SUBINT, no other IRQs
  341. */
  342.  
  343. static WRITE_HANDLER( irqctrl_w )
  344. {
  345.  
  346. //    logerror("CPU #0 - PC = %06X - $140005 <- %02X (old value: %02X)\n",cpu_get_pc(), data&0xFF, old_data&0xFF);
  347.  
  348. //    Bit 0 : SUBINT
  349.     if ( (wecleman_irqctrl & 1) && (!(data & 1)) )    // 1->0 transition
  350.         cpu_set_irq_line(1,4,HOLD_LINE);
  351.  
  352.  
  353. //    Bit 1 : NSUBRST
  354.     if (data & 2)
  355.         cpu_set_reset_line(1,CLEAR_LINE);
  356.     else
  357.         cpu_set_reset_line(1,ASSERT_LINE);
  358.  
  359.  
  360. //    Bit 2 : SOUND-ON
  361. //    Bit 3 : SOUNDRST
  362. //    Bit 4 : SCR-HCNT
  363. //    Bit 5 : SCR-VCNT
  364. //    Bit 6 : TV-KILL
  365.  
  366.     wecleman_irqctrl = data;    // latch the value
  367. }
  368.  
  369.  
  370.  
  371.  
  372.  
  373. static READ_HANDLER( accelerator_r )
  374. {
  375. #define MAX_ACCEL 0x80
  376.  
  377.     return (readinputport(4) & 1) ? MAX_ACCEL : 0;
  378. }
  379.  
  380.  
  381. /* This function allows the gear to be handled using two buttons
  382.    A macro is needed because wecleman sees the high gear when a
  383.    bit is on, hotchase when a bit is off */
  384.  
  385. #define READ_GEAR(_name_,_high_gear_) \
  386. READ_HANDLER( _name_ ) \
  387. { \
  388.     static int ret = (_high_gear_ ^ 1) << 5; /* start with low gear */ \
  389.     switch ( (readinputport(4) >> 2) & 3 ) \
  390.     { \
  391.         case 1 : ret = (_high_gear_ ^ 1) << 5;    break;    /* low gear */ \
  392.         case 2 : ret = (_high_gear_    ) << 5;    break;    /*  high gear */ \
  393.     } \
  394.     return (ret | readinputport(0));    /* previous value */ \
  395. }
  396.  
  397. READ_GEAR(wecleman_gear_r,1)
  398. READ_GEAR(hotchase_gear_r,0)
  399.  
  400.  
  401.  
  402. /* 140003.b (usually paired with a write to 140021.b)
  403.  
  404.     Bit:
  405.  
  406.     7-------    ?
  407.     -65-----    input selection (0-3)
  408.     ---43---    ?
  409.     -----2--    start light
  410.     ------10    ? out 1/2
  411.  
  412. */
  413. static WRITE_HANDLER( selected_ip_w )
  414. {
  415.     wecleman_selected_ip = data;    // latch the value
  416. }
  417.  
  418.  
  419. /* $140021.b - Return the previously selected input port's value */
  420. static READ_HANDLER( selected_ip_r )
  421. {
  422.     switch ( (wecleman_selected_ip >> 5) & 3 )
  423.     {                                                    // From WEC Le Mans Schems:
  424.         case 0:     return accelerator_r(offset);        // Accel - Schems: Accelevr
  425.         case 1:     return 0xffff;                        // ????? - Schems: Not Used
  426.         case 2:        return input_port_5_r(offset);        // Wheel - Schems: Handlevr
  427.         case 3:        return 0xffff;                        // Table - Schems: Turnvr
  428.  
  429.         default:    return 0xffff;
  430.     }
  431. }
  432.  
  433.  
  434.  
  435. /* Data is read from and written to *sharedram* */
  436. static READ_HANDLER( sharedram_r )                { return READ_WORD(&sharedram[offset]); }
  437. static WRITE_HANDLER( sharedram_w )    { COMBINE_WORD_MEM(&sharedram[offset], data); }
  438.  
  439.  
  440. /* Data is read from and written to *spriteram* */
  441. static READ_HANDLER( spriteram_word_r )            { return READ_WORD(&spriteram[offset]); }
  442. static WRITE_HANDLER( spriteram_word_w )    { COMBINE_WORD_MEM(&spriteram[offset], data); }
  443.  
  444.  
  445.  
  446.  
  447. /*    Word Blitter    -    Copies data around (Work RAM, Sprite RAM etc.)
  448.                         It's fed with a list of blits to do
  449.  
  450.     Offset:
  451.  
  452.     00.b        ? Number of words - 1 to add to address per transfer
  453.     01.b        ? logic function / blit mode
  454.     02.w        ? (always 0)
  455.     04.l        Source address (Base address of source data)
  456.     08.l        List of blits address
  457.     0c.l        Destination address
  458.     01.b        ? Number of transfers
  459.     10.b        Triggers the blit
  460.     11.b        Number of words per transfer
  461.  
  462.     The list contains 4 bytes per blit:
  463.  
  464.     Offset:
  465.  
  466.     00.w        ?
  467.     02.w        offset from Base address
  468.  
  469. */
  470.  
  471. static READ_HANDLER( blitter_r )
  472. {
  473.     return READ_WORD(&blitter_regs[offset]);
  474. }
  475.  
  476. static WRITE_HANDLER( blitter_w )
  477. {
  478.     COMBINE_WORD_MEM(&blitter_regs[offset],data);
  479.  
  480.     /* do a blit if $80010.b has been written */
  481.     if ((offset == 0x10) && (data&0x00FF0000))
  482.     {
  483.         /* 80000.b = ?? usually 0 - other values: 02 ; 00 - ? logic function ? */
  484.         /* 80001.b = ?? usually 0 - other values: 3f ; 01 - ? height ? */
  485.         int minterm        =    (READ_WORD(&blitter_regs[0x0]) & 0xFF00 ) >> 8;
  486.         int list_len    =    (READ_WORD(&blitter_regs[0x0]) & 0x00FF ) >> 0;
  487.  
  488.         /* 80002.w = ?? always 0 - ? increment per horizontal line ? */
  489.         /* no proof at all, it's always 0 */
  490. //        int srcdisp        =    READ_WORD(&blitter_regs[0x2])&0xFF00;
  491. //        int destdisp    =    READ_WORD(&blitter_regs[0x2])&0x00FF;
  492.  
  493.         /* 80004.l = source data address */
  494.         int src  =    (READ_WORD(&blitter_regs[0x4])<<16)+
  495.                      READ_WORD(&blitter_regs[0x6]);
  496.  
  497.         /* 80008.l = list of blits address */
  498.         int list =    (READ_WORD(&blitter_regs[0x8])<<16)+
  499.                       READ_WORD(&blitter_regs[0xA]);
  500.  
  501.         /* 8000C.l = destination address */
  502.         int dest =    (READ_WORD(&blitter_regs[0xC])<<16)+
  503.                      READ_WORD(&blitter_regs[0xE]);
  504.  
  505.         /* 80010.b = number of words to move */
  506.         int size =    (READ_WORD(&blitter_regs[0x10]))&0x00FF;
  507.  
  508. #if 0
  509.         {
  510.             int i;
  511.             logerror("Blitter (PC = %06X): ",cpu_get_pc());
  512.             for (i=0;i<0x12;i+=2) logerror("%04X ",READ_WORD(&blitter_regs[i]) );
  513.             logerror("\n");
  514.         }
  515. #endif
  516.  
  517.         /* Word aligned transfers only */
  518.         src  &= (~1);    list &= (~1);    dest &= (~1);
  519.  
  520.  
  521.         /* Two minterms / blit modes are used */
  522.         if (minterm != 2)
  523.         {
  524.             /* One single blit */
  525.             for ( ; size > 0 ; size--)
  526.             {
  527.                 /* maybe slower than a memcpy but safer (and errors are logged) */
  528.                 cpu_writemem24bew_word(dest,cpu_readmem24bew_word(src));
  529.                 src += 2;        dest += 2;
  530.             }
  531. //            src  += srcdisp;    dest += destdisp;
  532.         }
  533.         else
  534.         {
  535.             /* Number of blits in the list */
  536.             for ( ; list_len > 0 ; list_len-- )
  537.             {
  538.             int j;
  539.  
  540.                 /* Read offset of source from the list of blits */
  541.                 int addr = src + cpu_readmem24bew_word( list + 2 );
  542.  
  543.                 for (j = size; j > 0; j--)
  544.                 {
  545.                     cpu_writemem24bew_word(dest,cpu_readmem24bew_word(addr));
  546.                     dest += 2;    addr += 2;
  547.                 }
  548.                 dest += 16-size*2;    /* hack for the blit to Sprites RAM */
  549.                 list +=  4;
  550.             }
  551.  
  552.             /* hack for the blit to Sprites RAM - Sprite list end-marker */
  553.             cpu_writemem24bew_word(dest,0xFFFF);
  554.         }
  555.     } /* end blit */
  556. }
  557.  
  558.  
  559.  
  560. /*
  561. **
  562. **    Main cpu data
  563. **
  564. **
  565. */
  566.  
  567.  
  568.  
  569. /***************************************************************************
  570.                                 WEC Le Mans 24
  571. ***************************************************************************/
  572.  
  573. static WRITE_HANDLER( wecleman_soundlatch_w );
  574.  
  575. static struct MemoryReadAddress wecleman_readmem[] =
  576. {
  577.     { 0x000000, 0x03ffff, MRA_ROM                },    // ROM
  578.     { 0x040000, 0x043fff, MRA_BANK1                },    // RAM
  579.     { 0x060000, 0x060007, MRA_BANK2                },    // Video Registers? (only 60006.w is read)
  580.     { 0x080000, 0x080011, blitter_r                },    // Blitter (reading is for debug)
  581.     { 0x100000, 0x103fff, wecleman_pageram_r    },    // Background Layers
  582.     { 0x108000, 0x108fff, wecleman_txtram_r        },    // Text Layer
  583.     { 0x110000, 0x110fff, paletteram_word_r        },    // Palette
  584.     { 0x124000, 0x127fff, sharedram_r            },    // Shared with sub CPU
  585.     { 0x130000, 0x130fff, spriteram_word_r        },    // Sprites
  586.     // Input Ports:
  587.     { 0x140010, 0x140011, wecleman_gear_r        },    // Coins + brake + gear
  588.     { 0x140012, 0x140013, input_port_1_r        },    // ??
  589.     { 0x140014, 0x140015, input_port_2_r        },    // DSW
  590.     { 0x140016, 0x140017, input_port_3_r        },    // DSW
  591.     { 0x140020, 0x140021, selected_ip_r            },    // Accelerator or Wheel or ..
  592.     { -1 }
  593. };
  594.  
  595. static struct MemoryWriteAddress wecleman_writemem[] =
  596. {
  597.     { 0x000000, 0x03ffff, MWA_ROM                                            },    // ROM (03c000-03ffff used as RAM sometimes!)
  598.     { 0x040000, 0x043fff, MWA_BANK1                                            },    // RAM
  599.     { 0x060000, 0x060007, MWA_BANK2, &wecleman_unknown                        },    // Video Registers?
  600.     { 0x080000, 0x080011, blitter_w, &blitter_regs                            },    // Blitter
  601.     { 0x100000, 0x103fff, wecleman_pageram_w, &wecleman_pageram                },    // Background Layers
  602.     { 0x108000, 0x108fff, wecleman_txtram_w, &wecleman_txtram                },    // Text Layer
  603.     { 0x110000, 0x110fff, paletteram_SBGRBBBBGGGGRRRR_word_w, &paletteram    },    // Palette
  604.     { 0x124000, 0x127fff, sharedram_w, &sharedram                            },    // Shared with main CPU
  605.     { 0x130000, 0x130fff, spriteram_word_w, &spriteram, &spriteram_size        },    // Sprites
  606.     { 0x140000, 0x140001, wecleman_soundlatch_w                        },    // To sound CPU
  607.     { 0x140002, 0x140003, selected_ip_w                                },    // Selects accelerator / wheel / ..
  608.     { 0x140004, 0x140005, irqctrl_w                                    },    // Main CPU controls the other CPUs
  609.     { 0x140006, 0x140007, MWA_NOP                                    },    // Watchdog reset
  610.     { 0x140020, 0x140021, MWA_NOP                                    },    // Paired with writes to $140003
  611.     { 0x140030, 0x140031, MWA_BANK3                                    },    // ??
  612.     { -1 }
  613. };
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623. /***************************************************************************
  624.                                 Hot Chase
  625. ***************************************************************************/
  626.  
  627. static READ_HANDLER( hotchase_K051316_0_r )
  628. {
  629.     return K051316_0_r(offset >> 1);
  630. }
  631.  
  632. static READ_HANDLER( hotchase_K051316_1_r )
  633. {
  634.     return K051316_1_r(offset >> 1);
  635. }
  636.  
  637. static WRITE_HANDLER( hotchase_K051316_0_w )
  638. {
  639.     if ((data & 0x00ff0000) == 0)
  640.         K051316_0_w(offset >> 1, data & 0xff);
  641. }
  642.  
  643. static WRITE_HANDLER( hotchase_K051316_1_w )
  644. {
  645.     if ((data & 0x00ff0000) == 0)
  646.         K051316_1_w(offset >> 1, data & 0xff);
  647. }
  648.  
  649. static WRITE_HANDLER( hotchase_K051316_ctrl_0_w )
  650. {
  651.     if ((data & 0x00ff0000) == 0)
  652.         K051316_ctrl_0_w(offset >> 1, data & 0xff);
  653. }
  654.  
  655. static WRITE_HANDLER( hotchase_K051316_ctrl_1_w )
  656. {
  657.     if ((data & 0x00ff0000) == 0)
  658.         K051316_ctrl_1_w(offset >> 1, data & 0xff);
  659. }
  660.  
  661.  
  662. WRITE_HANDLER( hotchase_soundlatch_w );
  663.  
  664. static struct MemoryReadAddress hotchase_readmem[] =
  665. {
  666.     { 0x000000, 0x03ffff, MRA_ROM                },    // ROM
  667.     { 0x040000, 0x063fff, MRA_BANK1                },    // RAM (weird size!?)
  668.     { 0x080000, 0x080011, MRA_BANK2                },    // Blitter
  669.     { 0x100000, 0x100fff, hotchase_K051316_0_r },    // Background
  670.     { 0x102000, 0x102fff, hotchase_K051316_1_r },    // Foreground
  671.     { 0x110000, 0x111fff, paletteram_word_r        },    // Palette (only the first 2048 colors used)
  672.     { 0x120000, 0x123fff, sharedram_r            },    // Shared with sub CPU
  673.     { 0x130000, 0x130fff, spriteram_word_r        },    // Sprites
  674.     // Input Ports:
  675.     { 0x140006, 0x140007, MRA_NOP                },    // Watchdog reset
  676.     { 0x140010, 0x140011, hotchase_gear_r        },    // Coins + brake + gear
  677.     { 0x140012, 0x140013, input_port_1_r        },    // ?? bit 4 from sound cpu
  678.     { 0x140014, 0x140015, input_port_2_r        },    // DSW 2
  679.     { 0x140016, 0x140017, input_port_3_r        },    // DSW 1
  680.     { 0x140020, 0x140021, selected_ip_r            },    // Accelerator or Wheel or ..
  681. //    { 0x140022, 0x140023, MRA_NOP                },    // ??
  682.     { -1 }
  683. };
  684.  
  685. static struct MemoryWriteAddress hotchase_writemem[] =
  686. {
  687.     { 0x000000, 0x03ffff, MWA_ROM                                },    // ROM
  688.     { 0x040000, 0x063fff, MWA_BANK1                                },    // RAM (weird size!?)
  689.     { 0x080000, 0x080011, blitter_w, &blitter_regs                },    // Blitter
  690.     { 0x100000, 0x100fff, hotchase_K051316_0_w },        // Background
  691.     { 0x101000, 0x10101f, hotchase_K051316_ctrl_0_w },    // Background Ctrl
  692.     { 0x102000, 0x102fff, hotchase_K051316_1_w },        // Foreground
  693.     { 0x103000, 0x10301f, hotchase_K051316_ctrl_1_w },    // Foreground Ctrl
  694.     { 0x110000, 0x111fff, paletteram_SBGRBBBBGGGGRRRR_word_w, &paletteram    },    // Palette
  695.     { 0x120000, 0x123fff, sharedram_w, &sharedram                            },    // Shared with sub CPU
  696.     { 0x130000, 0x130fff, spriteram_word_w, &spriteram, &spriteram_size        },    // Sprites
  697.     // Input Ports:
  698.     { 0x140000, 0x140001, hotchase_soundlatch_w                    },    // To sound CPU
  699.     { 0x140002, 0x140003, selected_ip_w                            },    // Selects accelerator / wheel / ..
  700.     { 0x140004, 0x140005, irqctrl_w                                },    // Main CPU controls the other CPUs
  701.     { 0x140020, 0x140021, MWA_NOP                                },    // Paired with writes to $140003
  702. //    { 0x140030, 0x140031, MWA_NOP                                },    // ??
  703.     { -1 }
  704. };
  705.  
  706.  
  707.  
  708.  
  709.  
  710.  
  711. /*
  712. **
  713. **    Sub cpu data
  714. **
  715. **
  716. */
  717.  
  718. /***************************************************************************
  719.                                 WEC Le Mans 24
  720. ***************************************************************************/
  721.  
  722. static struct MemoryReadAddress wecleman_sub_readmem[] =
  723. {
  724.     { 0x000000, 0x00ffff, MRA_ROM        },    // ROM
  725.     { 0x060000, 0x060fff, MRA_BANK8        },    // Road
  726.     { 0x070000, 0x073fff, &sharedram_r    },    // RAM (Shared with main CPU)
  727.     { -1 }
  728. };
  729.  
  730. static struct MemoryWriteAddress wecleman_sub_writemem[] =
  731. {
  732.     { 0x000000, 0x00ffff, MWA_ROM        },    // ROM
  733.     { 0x060000, 0x060fff, MWA_BANK8, &wecleman_roadram, &wecleman_roadram_size },    // Road
  734.     { 0x070000, 0x073fff, sharedram_w    },    // RAM (Shared with main CPU)
  735.     { -1 }
  736. };
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749. /***************************************************************************
  750.                                 Hot Chase
  751. ***************************************************************************/
  752.  
  753.  
  754. static struct MemoryReadAddress hotchase_sub_readmem[] =
  755. {
  756.     { 0x000000, 0x01ffff, MRA_ROM        },    // ROM
  757.     { 0x020000, 0x020fff, MRA_BANK7        },    // Road
  758.     { 0x060000, 0x060fff, MRA_BANK8        },    // RAM
  759.     { 0x040000, 0x043fff, &sharedram_r    },    // Shared with main CPU
  760.     { -1 }
  761. };
  762.  
  763. static struct MemoryWriteAddress hotchase_sub_writemem[] =
  764. {
  765.     { 0x000000, 0x01ffff, MWA_ROM        },    // ROM
  766.     { 0x020000, 0x020fff, MWA_BANK7, &wecleman_roadram, &wecleman_roadram_size },    // Road
  767.     { 0x060000, 0x060fff, MWA_BANK8        },    // RAM
  768.     { 0x040000, 0x043fff, sharedram_w    },    // Shared with main CPU
  769.     { -1 }
  770. };
  771.  
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781. /*
  782. **
  783. **    Sound cpu data
  784. **
  785. **
  786. */
  787.  
  788. /***************************************************************************
  789.                                 WEC Le Mans 24
  790. ***************************************************************************/
  791.  
  792. /* 140001.b */
  793. WRITE_HANDLER( wecleman_soundlatch_w )
  794. {
  795.     soundlatch_w(0,data & 0xFF);
  796.     cpu_set_irq_line(2,0, HOLD_LINE);
  797. }
  798.  
  799.  
  800. /* Protection - an external multiplyer connected to the sound CPU */
  801. READ_HANDLER( multiply_r )
  802. {
  803.     return (multiply_reg[0] * multiply_reg[1]) & 0xFF;
  804. }
  805. WRITE_HANDLER( multiply_w )
  806. {
  807.     multiply_reg[offset] = data;
  808. }
  809.  
  810.  
  811. /*    K007232 registers reminder:
  812.  
  813. [Ch A]    [Ch B]        [Meaning]
  814. 00        06            address step    (low  byte)
  815. 01        07            address step    (high byte, max 1)
  816. 02        08            sample address    (low  byte)
  817. 03        09            sample address    (mid  byte)
  818. 04        0a            sample address    (high byte, max 1 -> max rom size: $20000)
  819. 05        0b            Reading this byte triggers the sample
  820.  
  821. [Ch A & B]
  822. 0c                    volume
  823. 0d                    play sample once or looped (2 channels -> 2 bits (0&1))
  824.  
  825. ** sample playing ends when a byte with bit 7 set is reached **/
  826.  
  827. WRITE_HANDLER( wecleman_K007232_bank_w )
  828. {
  829.     K007232_bankswitch(0, memory_region(REGION_SOUND1),
  830.                           memory_region((data & 1) ? REGION_SOUND1 : REGION_SOUND2) );
  831. }
  832.  
  833. static struct MemoryReadAddress wecleman_sound_readmem[] =
  834. {
  835.     { 0x0000, 0x7fff, MRA_ROM                    },    // ROM
  836.     { 0x8000, 0x83ff, MRA_RAM                    },    // RAM
  837.     { 0x9000, 0x9000, multiply_r                },    // Protection
  838.     { 0xa000, 0xa000, soundlatch_r                },    // From main CPU
  839.     { 0xb000, 0xb00d, K007232_read_port_0_r        },    // K007232 (Reading offset 5/b triggers the sample)
  840.     { 0xc001, 0xc001, YM2151_status_port_0_r    },    // YM2151
  841.     { -1 }
  842. };
  843.  
  844. static struct MemoryWriteAddress wecleman_sound_writemem[] =
  845. {
  846.     { 0x0000, 0x7fff, MWA_ROM                    },    // ROM
  847.     { 0x8000, 0x83ff, MWA_RAM                    },    // RAM
  848. //    { 0x8500, 0x8500, MWA_NOP                    },    // incresed with speed (global volume)?
  849.     { 0x9000, 0x9001, multiply_w                },    // Protection
  850. //    { 0x9006, 0x9006, MWA_NOP                    },    // ?
  851.     { 0xb000, 0xb00d, K007232_write_port_0_w    },    // K007232
  852.     { 0xc000, 0xc000, YM2151_register_port_0_w    },    // YM2151
  853.     { 0xc001, 0xc001, YM2151_data_port_0_w        },
  854.     { 0xf000, 0xf000, wecleman_K007232_bank_w    },    // Samples banking
  855.     { -1 }
  856. };
  857.  
  858.  
  859. /***************************************************************************
  860.                                 Hot Chase
  861. ***************************************************************************/
  862.  
  863. /* 140001.b */
  864. WRITE_HANDLER( hotchase_soundlatch_w )
  865. {
  866.     soundlatch_w(0,data & 0xFF);
  867.     cpu_set_irq_line(2,M6809_IRQ_LINE, HOLD_LINE);
  868. }
  869.  
  870. static struct K007232_interface hotchase_k007232_interface =
  871. {
  872.     3,
  873.     { REGION_SOUND1, REGION_SOUND2, REGION_SOUND3 },
  874.     { K007232_VOL( 33,MIXER_PAN_CENTER, 33,MIXER_PAN_CENTER ),
  875.       K007232_VOL( 33,MIXER_PAN_LEFT,   33,MIXER_PAN_RIGHT  ),
  876.       K007232_VOL( 33,MIXER_PAN_LEFT,   33,MIXER_PAN_RIGHT  ) },
  877.     { 0,0,0 }
  878. };
  879.  
  880. WRITE_HANDLER( hotchase_sound_control_w )
  881. {
  882.     int reg[8];
  883.  
  884.     reg[offset] = data;
  885.  
  886.     switch (offset)
  887.     {
  888.         case 0x0:    /* Change volume of voice A (l&r speaker at once) */
  889.         case 0x2:    /* for 3 chips.. */
  890.         case 0x4:
  891.                                 // chip, channel (l/r), volA, volB
  892.             K007232_set_volume( offset / 2,    0, (data >> 4) * 0x11, (reg[offset^1] >> 4) * 0x11);
  893.             K007232_set_volume( offset / 2,    1, (data & 15) * 0x11, (reg[offset^1] & 15) * 0x11);
  894.             break;
  895.  
  896.         case 0x1:    /* Change volume of voice B (l&r speaker at once) */
  897.         case 0x3:    /* for 3 chips.. */
  898.         case 0x5:
  899.                                 // chip, channel (l/r), volA, volB
  900.             K007232_set_volume( offset / 2,    0, (reg[offset^1] >> 4) * 0x11, (data >> 4) * 0x11);
  901.             K007232_set_volume( offset / 2,    1, (reg[offset^1] & 15) * 0x11, (data & 15) * 0x11);
  902.             break;
  903.  
  904.         case 0x06:    /* Bankswitch for chips 0 & 1 */
  905.         {
  906.             unsigned char *RAM0 = memory_region(hotchase_k007232_interface.bank[0]);
  907.             unsigned char *RAM1 = memory_region(hotchase_k007232_interface.bank[1]);
  908.  
  909.             int bank0_a = (data >> 1) & 1;
  910.             int bank1_a = (data >> 2) & 1;
  911.             int bank0_b = (data >> 3) & 1;
  912.             int bank1_b = (data >> 4) & 1;
  913.             // bit 6: chip 2 - ch0 ?
  914.             // bit 7: chip 2 - ch1 ?
  915.  
  916.             K007232_bankswitch(0, &RAM0[bank0_a*0x20000], &RAM0[bank0_b*0x20000]);
  917.             K007232_bankswitch(1, &RAM1[bank1_a*0x20000], &RAM1[bank1_b*0x20000]);
  918.         }
  919.         break;
  920.  
  921.         case 0x07:    /* Bankswitch for chip 2 */
  922.         {
  923.             unsigned char *RAM2 = memory_region(hotchase_k007232_interface.bank[2]);
  924.  
  925.             int bank2_a = (data >> 0) & 7;
  926.             int bank2_b = (data >> 3) & 7;
  927.  
  928.             K007232_bankswitch(2, &RAM2[bank2_a*0x20000], &RAM2[bank2_b*0x20000]);
  929.         }
  930.         break;
  931.     }
  932. }
  933.  
  934.  
  935. /* Read and write handlers for one K007232 chip:
  936.    even and odd register are mapped swapped */
  937.  
  938. #define HOTCHASE_K007232_RW(_chip_) \
  939. READ_HANDLER( hotchase_K007232_##_chip_##_r ) \
  940. { \
  941.     return K007232_read_port_##_chip_##_r(offset ^ 1); \
  942. } \
  943. WRITE_HANDLER( hotchase_K007232_##_chip_##_w ) \
  944. { \
  945.     K007232_write_port_##_chip_##_w(offset ^ 1, data); \
  946. } \
  947.  
  948. /* 3 x K007232 */
  949. HOTCHASE_K007232_RW(0)
  950. HOTCHASE_K007232_RW(1)
  951. HOTCHASE_K007232_RW(2)
  952.  
  953.  
  954.  
  955. static struct MemoryReadAddress hotchase_sound_readmem[] =
  956. {
  957.     { 0x0000, 0x07ff, MRA_RAM                    },    // RAM
  958.     { 0x1000, 0x100d, hotchase_K007232_0_r        },    // 3 x  K007232
  959.     { 0x2000, 0x200d, hotchase_K007232_1_r        },
  960.     { 0x3000, 0x300d, hotchase_K007232_2_r        },
  961.     { 0x6000, 0x6000, soundlatch_r                },    // From main CPU (Read on IRQ)
  962.     { 0x8000, 0xffff, MRA_ROM                    },    // ROM
  963.     { -1 }
  964. };
  965.  
  966. static struct MemoryWriteAddress hotchase_sound_writemem[] =
  967. {
  968.     { 0x0000, 0x07ff, MWA_RAM                    },    // RAM
  969.     { 0x1000, 0x100d, hotchase_K007232_0_w        },    // 3 x K007232
  970.     { 0x2000, 0x200d, hotchase_K007232_1_w        },
  971.     { 0x3000, 0x300d, hotchase_K007232_2_w        },
  972.     { 0x4000, 0x4007, hotchase_sound_control_w    },    // Sound volume, banking, etc.
  973.     { 0x5000, 0x5000, MWA_NOP                    },    // ? (written with 0 on IRQ, 1 on FIRQ)
  974.     { 0x7000, 0x7000, MWA_NOP                    },    // Command acknowledge ?
  975.     { 0x8000, 0xffff, MWA_ROM                    },    // ROM
  976.     { -1 }
  977. };
  978.  
  979.  
  980.  
  981.  
  982.  
  983. /***************************************************************************
  984.  
  985.                             Input Ports
  986.  
  987. ***************************************************************************/
  988.  
  989. // Fake input port to read the status of the four buttons
  990. // Used to implement both the accelerator and the shift using 2 buttons
  991.  
  992. #define BUTTONS_STATUS \
  993.     PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) \
  994.     PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) \
  995.     PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) \
  996.     PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON4 )
  997.  
  998.  
  999.  
  1000.  
  1001. #define DRIVING_WHEEL \
  1002.  PORT_ANALOG( 0xff, 0x80, IPT_AD_STICK_X | IPF_CENTER, 50, 5, 0, 0xff)
  1003.  
  1004.  
  1005.  
  1006.  
  1007. #define CONTROLS_AND_COINS(_default_) \
  1008.     PORT_BIT(  0x01, _default_, IPT_COIN1   ) \
  1009.     PORT_BIT(  0x02, _default_, IPT_COIN2   ) \
  1010.     PORT_BITX( 0x04, _default_, IPT_SERVICE, DEF_STR( Service_Mode ), KEYCODE_F2, IP_JOY_NONE ) \
  1011.     PORT_BIT(  0x08, _default_, IPT_COIN3   )                    /* Called "service" */ \
  1012.     PORT_BIT(  0x10, _default_, IPT_START1  )                    /* Start */ \
  1013. /*    PORT_BIT(  0x20, _default_, IPT_BUTTON3 | IPF_TOGGLE ) */    /* Shift (we handle this with 2 buttons) */ \
  1014.     PORT_BIT(  0x40, _default_, IPT_BUTTON2 )                    /* Brake */ \
  1015.     PORT_BIT(  0x80, _default_, IPT_UNKNOWN )                    /* ? */
  1016.  
  1017.  
  1018. /***************************************************************************
  1019.                                 WEC Le Mans 24
  1020. ***************************************************************************/
  1021.  
  1022. INPUT_PORTS_START( wecleman )
  1023.  
  1024.     PORT_START      /* IN0 - Controls and Coins - $140011.b */
  1025.     CONTROLS_AND_COINS(IP_ACTIVE_HIGH)
  1026.  
  1027.     PORT_START      /* IN1 - Motor? - $140013.b */
  1028.     PORT_BIT( 0x01, IP_ACTIVE_LOW,  IPT_UNKNOWN )    // ? right sw
  1029.     PORT_BIT( 0x02, IP_ACTIVE_LOW,  IPT_UNKNOWN )    // ? left  sw
  1030.     PORT_BIT( 0x04, IP_ACTIVE_LOW,  IPT_UNKNOWN )    // ? thermo
  1031.     PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )    // ? from sound cpu ?
  1032.     PORT_BIT( 0x10, IP_ACTIVE_LOW,  IPT_UNKNOWN )
  1033.     PORT_BIT( 0x20, IP_ACTIVE_LOW,  IPT_UNKNOWN )
  1034.     PORT_BIT( 0x40, IP_ACTIVE_LOW,  IPT_UNKNOWN )
  1035.     PORT_BIT( 0x80, IP_ACTIVE_LOW,  IPT_UNKNOWN )
  1036.  
  1037.     PORT_START    /* IN2 - DSW A (Coinage) - $140015.b */
  1038.     PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) )
  1039.     PORT_DIPSETTING(    0x02, DEF_STR( 4C_1C ) )
  1040.     PORT_DIPSETTING(    0x05, DEF_STR( 3C_1C ) )
  1041.     PORT_DIPSETTING(    0x08, DEF_STR( 2C_1C ) )
  1042.     PORT_DIPSETTING(    0x04, DEF_STR( 3C_2C ) )
  1043.     PORT_DIPSETTING(    0x01, DEF_STR( 4C_3C ) )
  1044.     PORT_DIPSETTING(    0x0f, DEF_STR( 1C_1C ) )
  1045.     PORT_DIPSETTING(    0x03, DEF_STR( 3C_4C ) )
  1046.     PORT_DIPSETTING(    0x07, DEF_STR( 2C_3C ) )
  1047.     PORT_DIPSETTING(    0x0e, DEF_STR( 1C_2C ) )
  1048.     PORT_DIPSETTING(    0x06, DEF_STR( 2C_5C ) )
  1049.     PORT_DIPSETTING(    0x0d, DEF_STR( 1C_3C ) )
  1050.     PORT_DIPSETTING(    0x0c, DEF_STR( 1C_4C ) )
  1051.     PORT_DIPSETTING(    0x0b, DEF_STR( 1C_5C ) )
  1052.     PORT_DIPSETTING(    0x0a, DEF_STR( 1C_6C ) )
  1053.     PORT_DIPSETTING(    0x09, DEF_STR( 1C_7C ) )
  1054.     PORT_DIPSETTING(    0x00, DEF_STR( Free_Play ) )
  1055.     PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) )
  1056.     PORT_DIPSETTING(    0x20, DEF_STR( 4C_1C ) )
  1057.     PORT_DIPSETTING(    0x50, DEF_STR( 3C_1C ) )
  1058.     PORT_DIPSETTING(    0x80, DEF_STR( 2C_1C ) )
  1059.     PORT_DIPSETTING(    0x40, DEF_STR( 3C_2C ) )
  1060.     PORT_DIPSETTING(    0x10, DEF_STR( 4C_3C ) )
  1061.     PORT_DIPSETTING(    0xf0, DEF_STR( 1C_1C ) )
  1062.     PORT_DIPSETTING(    0x30, DEF_STR( 3C_4C ) )
  1063.     PORT_DIPSETTING(    0x70, DEF_STR( 2C_3C ) )
  1064.     PORT_DIPSETTING(    0xe0, DEF_STR( 1C_2C ) )
  1065.     PORT_DIPSETTING(    0x60, DEF_STR( 2C_5C ) )
  1066.     PORT_DIPSETTING(    0xd0, DEF_STR( 1C_3C ) )
  1067.     PORT_DIPSETTING(    0xc0, DEF_STR( 1C_4C ) )
  1068.     PORT_DIPSETTING(    0xb0, DEF_STR( 1C_5C ) )
  1069.     PORT_DIPSETTING(    0xa0, DEF_STR( 1C_6C ) )
  1070.     PORT_DIPSETTING(    0x90, DEF_STR( 1C_7C ) )
  1071.     PORT_DIPSETTING(    0x00, DEF_STR( Unknown ) )
  1072.  
  1073.     PORT_START    /* IN3 - DSW B (options) - $140017.b */
  1074.     PORT_DIPNAME( 0x01, 0x01, "Speed Unit" )
  1075.     PORT_DIPSETTING(    0x01, "Km/h" )
  1076.     PORT_DIPSETTING(    0x00, "mph" )
  1077.     PORT_DIPNAME( 0x02, 0x02, "Unknown B-1" )    // single
  1078.     PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
  1079.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1080.     PORT_DIPNAME( 0x04, 0x04, "Unknown B-2" )
  1081.     PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
  1082.     PORT_DIPNAME( 0x18, 0x18, DEF_STR( Difficulty ) )
  1083.     PORT_DIPSETTING(    0x18, "Easy" )            // 66 seconds at the start
  1084.     PORT_DIPSETTING(    0x10, "Normal" )        // 64
  1085.     PORT_DIPSETTING(    0x08, "Hard" )            // 62
  1086.     PORT_DIPSETTING(    0x00, "Hardest" )        // 60
  1087.     PORT_DIPNAME( 0x20, 0x00, DEF_STR( Demo_Sounds ) )
  1088.     PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
  1089.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1090.     PORT_DIPNAME( 0x40, 0x40, "Unknown B-6" )
  1091.     PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
  1092.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1093.     PORT_DIPNAME( 0x80, 0x80, "Unknown B-7" )
  1094.     PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
  1095.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1096.  
  1097.     PORT_START    /* IN4 - Fake input port - Buttons status */
  1098.     BUTTONS_STATUS
  1099.  
  1100.     PORT_START    /* IN5 - Driving Wheel - $140021.b (2) */
  1101.     DRIVING_WHEEL
  1102.  
  1103. INPUT_PORTS_END
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117. /***************************************************************************
  1118.                                 Hot Chase
  1119. ***************************************************************************/
  1120.  
  1121. INPUT_PORTS_START( hotchase )
  1122.  
  1123.     PORT_START      /* IN0 - Controls and Coins - $140011.b */
  1124.     CONTROLS_AND_COINS(IP_ACTIVE_LOW)
  1125.  
  1126.     PORT_START      /* IN1 - Motor? - $140013.b */
  1127.     PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )    // ? right sw
  1128.     PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )    // ? left  sw
  1129.     PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )    // ? thermo
  1130.     PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNKNOWN )    // ? from sound cpu ?
  1131.     PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN )
  1132.     PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN )
  1133.     PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN )
  1134.     PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN )
  1135.  
  1136.     PORT_START    /* IN2 - DSW 2 (options) - $140015.b */
  1137.     PORT_DIPNAME( 0x01, 0x01, "Unknown 2-0" )    // single
  1138.     PORT_DIPSETTING(    0x01, DEF_STR( Off ) )
  1139.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1140.     PORT_DIPNAME( 0x02, 0x02, "Unknown 2-1" )    // single (wheel related)
  1141.     PORT_DIPSETTING(    0x02, DEF_STR( Off ) )
  1142.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1143.     PORT_DIPNAME( 0x04, 0x04, "Unknown 2-2" )
  1144.     PORT_DIPSETTING(    0x04, DEF_STR( Off ) )
  1145.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1146.     PORT_DIPNAME( 0x18, 0x18, "Unknown 2-3&4" )
  1147.     PORT_DIPSETTING(    0x18, "0" )
  1148.     PORT_DIPSETTING(    0x10, "4" )
  1149.     PORT_DIPSETTING(    0x08, "8" )
  1150.     PORT_DIPSETTING(    0x00, "c" )
  1151.     PORT_DIPNAME( 0x20, 0x20, "Unknown 2-5" )    // single
  1152.     PORT_DIPSETTING(    0x20, DEF_STR( Off ) )
  1153.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1154. /* wheel <-> brake ; accel -> start */
  1155.     PORT_DIPNAME( 0x40, 0x40, "Unknown 2-6" )    // single (wheel<->brake)
  1156.     PORT_DIPSETTING(    0x40, DEF_STR( Off ) )
  1157.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1158.     PORT_DIPNAME( 0x80, 0x80, "Unknown 2-7" )    // single
  1159.     PORT_DIPSETTING(    0x80, DEF_STR( Off ) )
  1160.     PORT_DIPSETTING(    0x00, DEF_STR( On ) )
  1161.  
  1162.     PORT_START    /* IN3 - DSW 1 (Coinage) - $140017.b */
  1163.     PORT_DIPNAME( 0x0f, 0x0f, DEF_STR( Coin_A ) )
  1164.     PORT_DIPSETTING(    0x02, DEF_STR( 5C_1C ) )
  1165.     PORT_DIPSETTING(    0x04, DEF_STR( 4C_1C ) )
  1166.     PORT_DIPSETTING(    0x07, DEF_STR( 3C_1C ) )
  1167.     PORT_DIPSETTING(    0x0a, DEF_STR( 2C_1C ) )
  1168.     PORT_DIPSETTING(    0x01, DEF_STR( 5C_3C ) )
  1169.     PORT_DIPSETTING(    0x06, DEF_STR( 3C_2C ) )
  1170.     PORT_DIPSETTING(    0x03, DEF_STR( 4C_3C ) )
  1171.     PORT_DIPSETTING(    0x0f, DEF_STR( 1C_1C ) )
  1172.     PORT_DIPSETTING(    0x05, DEF_STR( 3C_4C ) )
  1173.     PORT_DIPSETTING(    0x09, DEF_STR( 2C_3C ) )
  1174.     PORT_DIPSETTING(    0x0e, DEF_STR( 1C_2C ) )
  1175.     PORT_DIPSETTING(    0x08, DEF_STR( 2C_5C ) )
  1176.     PORT_DIPSETTING(    0x0d, DEF_STR( 1C_3C ) )
  1177.     PORT_DIPSETTING(    0x0c, DEF_STR( 1C_4C ) )
  1178.     PORT_DIPSETTING(    0x0b, DEF_STR( 1C_5C ) )
  1179.     PORT_DIPSETTING(    0x00, DEF_STR( Free_Play ) )
  1180.     PORT_DIPNAME( 0xf0, 0xf0, DEF_STR( Coin_B ) )
  1181.     PORT_DIPSETTING(    0x20, DEF_STR( 5C_1C ) )
  1182.     PORT_DIPSETTING(    0x70, DEF_STR( 3C_1C ) )
  1183.     PORT_DIPSETTING(    0xa0, DEF_STR( 2C_1C ) )
  1184.     PORT_DIPSETTING(    0x10, DEF_STR( 5C_3C ) )
  1185.     PORT_DIPSETTING(    0x60, DEF_STR( 3C_2C ) )
  1186.     PORT_DIPSETTING(    0x30, DEF_STR( 4C_3C ) )
  1187.     PORT_DIPSETTING(    0xf0, DEF_STR( 1C_1C ) )
  1188.     PORT_DIPSETTING(    0x50, DEF_STR( 3C_4C ) )
  1189.     PORT_DIPSETTING(    0x90, DEF_STR( 2C_3C ) )
  1190.     PORT_DIPSETTING(    0xe0, DEF_STR( 1C_2C ) )
  1191.     PORT_DIPSETTING(    0x80, DEF_STR( 2C_5C ) )
  1192.     PORT_DIPSETTING(    0xd0, DEF_STR( 1C_3C ) )
  1193.     PORT_DIPSETTING(    0xc0, DEF_STR( 1C_4C ) )
  1194.     PORT_DIPSETTING(    0xb0, DEF_STR( 1C_5C ) )
  1195.     PORT_DIPSETTING(    0x00, "1 Coin/99 Credits" )
  1196. //    PORT_DIPSETTING(    0x40, "0C_0C" )    // Coin B insertion freezes the game!
  1197.  
  1198.     PORT_START    /* IN4 - Fake input port - Buttons status */
  1199.     BUTTONS_STATUS
  1200.  
  1201.     PORT_START    /* IN5 - Driving Wheel - $140021.b (2) */
  1202.     DRIVING_WHEEL
  1203.  
  1204. INPUT_PORTS_END
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214. /***************************************************************************
  1215.  
  1216.                                 Graphics Layout
  1217.  
  1218. ***************************************************************************/
  1219.  
  1220.  
  1221. /***************************************************************************
  1222.                                 WEC Le Mans 24
  1223. ***************************************************************************/
  1224.  
  1225. static struct GfxLayout wecleman_bg_layout =
  1226. {
  1227.     8,8,
  1228.     8*0x8000*3/(8*8*3),
  1229.     3,
  1230.     { 0,0x8000*8,0x8000*8*2 },
  1231.     {0,7,6,5,4,3,2,1},
  1232.     {0*8,1*8,2*8,3*8,4*8,5*8,6*8,7*8},
  1233.     8*8
  1234. };
  1235.  
  1236. /* We draw the road, made of 512 pixel lines, using 64x1 tiles */
  1237. static struct GfxLayout wecleman_road_layout =
  1238. {
  1239.     64,1,
  1240.     8*0x4000*3/(64*1*3),
  1241.     3,
  1242.     { 0x4000*8*2,0x4000*8*1,0x4000*8*0 },
  1243.     {0,7,6,5,4,3,2,1,
  1244.      8,15,14,13,12,11,10,9,
  1245.      16,23,22,21,20,19,18,17,
  1246.      24,31,30,29,28,27,26,25,
  1247.  
  1248.      0+32,7+32,6+32,5+32,4+32,3+32,2+32,1+32,
  1249.      8+32,15+32,14+32,13+32,12+32,11+32,10+32,9+32,
  1250.      16+32,23+32,22+32,21+32,20+32,19+32,18+32,17+32,
  1251.      24+32,31+32,30+32,29+32,28+32,27+32,26+32,25+32},
  1252.     {0},
  1253.     64*1
  1254. };
  1255.  
  1256.  
  1257. static struct GfxDecodeInfo wecleman_gfxdecodeinfo[] =
  1258. {
  1259. //      REGION_GFX1 holds sprite, which are not decoded here
  1260.     { REGION_GFX2, 0, &wecleman_bg_layout,   0, 2048/8 }, // [0] bg + fg + txt
  1261.     { REGION_GFX3, 0, &wecleman_road_layout, 0, 2048/8 }, // [1] road
  1262.     { -1 }
  1263. };
  1264.  
  1265.  
  1266.  
  1267. /***************************************************************************
  1268.                                 Hot Chase
  1269. ***************************************************************************/
  1270.  
  1271.  
  1272. /* We draw the road, made of 512 pixel lines, using 64x1 tiles */
  1273. static struct GfxLayout hotchase_road_layout =
  1274. {
  1275.     64,1,
  1276.     8*0x20000/(64*1*4),
  1277.     4,
  1278.     { 0, 1, 2, 3 },
  1279.     {0*4,1*4,2*4,3*4,4*4,5*4,6*4,7*4,
  1280.      8*4,9*4,10*4,11*4,12*4,13*4,14*4,15*4,
  1281.      16*4,17*4,18*4,19*4,20*4,21*4,22*4,23*4,
  1282.      24*4,25*4,26*4,27*4,28*4,29*4,30*4,31*4,
  1283.  
  1284.      32*4,33*4,34*4,35*4,36*4,37*4,38*4,39*4,
  1285.      40*4,41*4,42*4,43*4,44*4,45*4,46*4,47*4,
  1286.      48*4,49*4,50*4,51*4,52*4,53*4,54*4,55*4,
  1287.      56*4,57*4,58*4,59*4,60*4,61*4,62*4,63*4},
  1288.     {0},
  1289.     64*1*4
  1290. };
  1291.  
  1292.  
  1293. static struct GfxDecodeInfo hotchase_gfxdecodeinfo[] =
  1294. {
  1295. //    REGION_GFX1 holds sprite, which are not decoded here
  1296. //    REGION_GFX2 and 3 are for the 051316
  1297.     { REGION_GFX4, 0, &hotchase_road_layout, 0x70*16, 16 },    // road
  1298.     { -1 }
  1299. };
  1300.  
  1301.  
  1302.  
  1303.  
  1304. /***************************************************************************
  1305.                                 WEC Le Mans 24
  1306. ***************************************************************************/
  1307.  
  1308.  
  1309.  
  1310.  
  1311. static int wecleman_interrupt( void )
  1312. {
  1313.     if (cpu_getiloops() == 0)    return 4;    /* once */
  1314.     else                        return 5;    /* to read input ports */
  1315. }
  1316.  
  1317.  
  1318. static struct YM2151interface ym2151_interface =
  1319. {
  1320.     1,
  1321.     3579545,    /* same as sound cpu */
  1322.     { 80 },
  1323.     { 0  }
  1324. };
  1325.  
  1326.  
  1327.  
  1328. static struct K007232_interface wecleman_k007232_interface =
  1329. {
  1330.     1,
  1331.     { REGION_SOUND1 },    /* but the 2 channels use different ROMs !*/
  1332.     { K007232_VOL( 20,MIXER_PAN_LEFT, 20,MIXER_PAN_RIGHT ) },
  1333.     {0}
  1334. };
  1335.  
  1336.  
  1337.  
  1338. void wecleman_init_machine(void)
  1339. {
  1340.     K007232_bankswitch(0,    memory_region(REGION_SOUND1), /* the 2 channels use different ROMs */
  1341.                             memory_region(REGION_SOUND2) );
  1342. }
  1343.  
  1344.  
  1345. static struct MachineDriver machine_driver_wecleman =
  1346. {
  1347.     {
  1348.         {
  1349.             CPU_M68000,
  1350.             10000000,        /* Schems show 10MHz */
  1351.             wecleman_readmem,wecleman_writemem,0,0,
  1352.             wecleman_interrupt, 5 + 1,    /* in order to read the inputs once per frame */
  1353.         },
  1354.         {
  1355.             CPU_M68000,
  1356.             10000000,        /* Schems show 10MHz */
  1357.             wecleman_sub_readmem,wecleman_sub_writemem,0,0,
  1358.             ignore_interrupt,1,        /* lev 4 irq generated by main CPU */
  1359.         },
  1360.         {
  1361. /* Schems: can be reset, no nmi, soundlatch, 3.58MHz */
  1362.             CPU_Z80 | CPU_AUDIO_CPU,
  1363.             3579545,
  1364.             wecleman_sound_readmem,wecleman_sound_writemem,0,0,
  1365.             ignore_interrupt,1, /* irq caused by main cpu */
  1366.         },
  1367.     },
  1368.     60,DEFAULT_60HZ_VBLANK_DURATION,
  1369.     1,
  1370.     wecleman_init_machine,
  1371.  
  1372.     /* video hardware */
  1373.     320, 224, { 0, 320-1, 0, 224-1 },
  1374.  
  1375.     wecleman_gfxdecodeinfo,
  1376.     2048, 2048,
  1377.     0,
  1378.  
  1379.     VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE,
  1380.     0,
  1381.     wecleman_vh_start,
  1382.     0,
  1383.     wecleman_vh_screenrefresh,
  1384.  
  1385.     /* sound hardware */
  1386.     0,0,0,0,
  1387.     {
  1388.         {
  1389.             SOUND_YM2151,
  1390.             &ym2151_interface
  1391.         },
  1392.         {
  1393.             SOUND_K007232,
  1394.             &wecleman_k007232_interface
  1395.         },
  1396.     }
  1397. };
  1398.  
  1399.  
  1400.  
  1401.  
  1402.  
  1403. /***************************************************************************
  1404.                                 Hot Chase
  1405. ***************************************************************************/
  1406.  
  1407.  
  1408.  
  1409. void hotchase_init_machine(void)        {                        }
  1410. int  hotchase_interrupt( void )            {return 4;                }
  1411. int  hotchase_sound_interrupt(void)        {return M6809_INT_FIRQ;    }
  1412.  
  1413. static struct MachineDriver machine_driver_hotchase =
  1414. {
  1415.     {
  1416.         {
  1417.             CPU_M68000,
  1418.             10000000,        /* 10 MHz - PCB is drawn in one set's readme */
  1419.             hotchase_readmem,hotchase_writemem,0,0,
  1420.             hotchase_interrupt,1,
  1421.         },
  1422.         {
  1423.             CPU_M68000,
  1424.             10000000,        /* 10 MHz - PCB is drawn in one set's readme */
  1425.             hotchase_sub_readmem,hotchase_sub_writemem,0,0,
  1426.             ignore_interrupt,1,        /* lev 4 irq generated by main CPU */
  1427.         },
  1428.         {
  1429.             CPU_M6809 | CPU_AUDIO_CPU,
  1430.             3579545,        /* 3.579 MHz - PCB is drawn in one set's readme */
  1431.             hotchase_sound_readmem,hotchase_sound_writemem,0,0,
  1432.             hotchase_sound_interrupt,8, /* FIRQ, while IRQ is caused by main cpu */
  1433.                                         /* Amuse: every 2 ms */
  1434.         },
  1435.     },
  1436.     60,DEFAULT_60HZ_VBLANK_DURATION,
  1437.     1,
  1438.     hotchase_init_machine,
  1439.  
  1440.     /* video hardware */
  1441.     320, 224, { 0, 320-1, 0, 224-1 },
  1442.  
  1443.     hotchase_gfxdecodeinfo,
  1444.     2048, 2048,
  1445.     0,
  1446.  
  1447.     VIDEO_TYPE_RASTER | VIDEO_MODIFIES_PALETTE,
  1448.     0,
  1449.     hotchase_vh_start,
  1450.     hotchase_vh_stop,
  1451.     hotchase_vh_screenrefresh,
  1452.  
  1453.     /* sound hardware */
  1454.     0,0,0,0,
  1455.     {
  1456.         {
  1457.             SOUND_K007232,
  1458.             &hotchase_k007232_interface
  1459.         }
  1460.     }
  1461. };
  1462.  
  1463.  
  1464.  
  1465. /***************************************************************************
  1466.  
  1467.                                 ROMs Loading
  1468.  
  1469. ***************************************************************************/
  1470.  
  1471.  
  1472.  
  1473. /***************************************************************************
  1474.                                 WEC Le Mans 24
  1475. ***************************************************************************/
  1476.  
  1477. ROM_START( wecleman )
  1478.  
  1479.     ROM_REGION( 0x40000, REGION_CPU1 )        /* Main CPU Code */
  1480.     ROM_LOAD_EVEN( "602f08.17h", 0x00000, 0x10000, 0x493b79d3 )
  1481.     ROM_LOAD_ODD ( "602f11.23h", 0x00000, 0x10000, 0x6bb4f1fa )
  1482.     ROM_LOAD_EVEN( "602a09.18h", 0x20000, 0x10000, 0x8a9d756f )
  1483.     ROM_LOAD_ODD ( "602a10.22h", 0x20000, 0x10000, 0x569f5001 )
  1484.  
  1485.     ROM_REGION( 0x10000, REGION_CPU2 )        /* Sub CPU Code */
  1486.     ROM_LOAD_EVEN( "602a06.18a", 0x00000, 0x08000, 0xe12c0d11 )
  1487.     ROM_LOAD_ODD(  "602a07.20a", 0x00000, 0x08000, 0x47968e51 )
  1488.  
  1489.     ROM_REGION( 0x10000, REGION_CPU3 )        /* Sound CPU Code */
  1490.     ROM_LOAD( "602a01.6d",  0x00000, 0x08000, 0xdeafe5f1 )
  1491.  
  1492.     ROM_REGION( 0x200000 * 2, REGION_GFX1 )    /* x2, do not dispose */
  1493.     ROM_LOAD( "602a25.12e", 0x000000, 0x20000, 0x0eacf1f9 )    // zooming sprites
  1494.     ROM_LOAD( "602a26.14e", 0x020000, 0x20000, 0x2182edaf )
  1495.     ROM_LOAD( "602a27.15e", 0x040000, 0x20000, 0xb22f08e9 )
  1496.     ROM_LOAD( "602a28.17e", 0x060000, 0x20000, 0x5f6741fa )
  1497.     ROM_LOAD( "602a21.6e",  0x080000, 0x20000, 0x8cab34f1 )
  1498.     ROM_LOAD( "602a22.7e",  0x0a0000, 0x20000, 0xe40303cb )
  1499.     ROM_LOAD( "602a23.9e",  0x0c0000, 0x20000, 0x75077681 )
  1500.     ROM_LOAD( "602a24.10e", 0x0e0000, 0x20000, 0x583dadad )
  1501.     ROM_LOAD( "602a17.12c", 0x100000, 0x20000, 0x31612199 )
  1502.     ROM_LOAD( "602a18.14c", 0x120000, 0x20000, 0x3f061a67 )
  1503.     ROM_LOAD( "602a19.15c", 0x140000, 0x20000, 0x5915dbc5 )
  1504.     ROM_LOAD( "602a20.17c", 0x160000, 0x20000, 0xf87e4ef5 )
  1505.     ROM_LOAD( "602a13.6c",  0x180000, 0x20000, 0x5d3589b8 )
  1506.     ROM_LOAD( "602a14.7c",  0x1a0000, 0x20000, 0xe3a75f6c )
  1507.     ROM_LOAD( "602a15.9c",  0x1c0000, 0x20000, 0x0d493c9f )
  1508.     ROM_LOAD( "602a16.10c", 0x1e0000, 0x20000, 0xb08770b3 )
  1509.  
  1510.     ROM_REGION( 0x18000, REGION_GFX2 | REGIONFLAG_DISPOSE )
  1511.     ROM_LOAD( "602a31.26g", 0x000000, 0x08000, 0x01fa40dd )    // layers
  1512.     ROM_LOAD( "602a30.24g", 0x008000, 0x08000, 0xbe5c4138 )
  1513.     ROM_LOAD( "602a29.23g", 0x010000, 0x08000, 0xf1a8d33e )
  1514.  
  1515.     ROM_REGION( 0x0c000, REGION_GFX3 | REGIONFLAG_DISPOSE )
  1516.     ROM_LOAD( "602a04.11e", 0x000000, 0x08000, 0xade9f359 ) // road
  1517.     ROM_LOAD( "602a05.13e", 0x008000, 0x04000, 0xf22b7f2b )
  1518.  
  1519.     ROM_REGION( 0x20000, REGION_SOUND1 )    /* Samples (Channel A) */
  1520.     ROM_LOAD( "602a03.10a", 0x00000, 0x20000, 0x31392b01 )
  1521.  
  1522.     ROM_REGION( 0x20000, REGION_SOUND2 )    /* Samples (Channel B) */
  1523.     ROM_LOAD( "602a02.8a",  0x00000, 0x20000, 0xe2be10ae )
  1524.  
  1525.     ROM_REGION( 0x04000, REGION_USER1 )
  1526.     ROM_LOAD( "602a12.1a",  0x000000, 0x04000, 0x77b9383d )    // ??
  1527.  
  1528. ROM_END
  1529.  
  1530.  
  1531.  
  1532. void wecleman_unpack_sprites(void)
  1533. {
  1534.     const int region        =    REGION_GFX1;    // sprites
  1535.  
  1536.     const unsigned int len    =    memory_region_length(region);
  1537.     unsigned char *src        =    memory_region(region) + len / 2 - 1;
  1538.     unsigned char *dst        =    memory_region(region) + len - 1;
  1539.  
  1540.     while(dst > src)
  1541.     {
  1542.         unsigned char data = *src--;
  1543.         if( (data&0xf0) == 0xf0 ) data &= 0x0f;
  1544.         if( (data&0x0f) == 0x0f ) data &= 0xf0;
  1545.         *dst-- = data & 0xF;    *dst-- = data >> 4;
  1546.     }
  1547. }
  1548.  
  1549.  
  1550.  
  1551. /* Unpack sprites data and do some patching */
  1552. void init_wecleman(void)
  1553. {
  1554.     unsigned char *RAM;
  1555.     int i;
  1556.  
  1557. /* Optional code patches */
  1558.  
  1559.     /* Main CPU patches */
  1560.     RAM = memory_region(REGION_CPU1);
  1561. //    WRITE_WORD (&RAM[0x08c2],0x601e);    // faster self test
  1562.  
  1563.     /* Sub CPU patches */
  1564.     RAM = memory_region(REGION_CPU2);
  1565.  
  1566.     /* Sound CPU patches */
  1567.     RAM = memory_region(REGION_CPU3);
  1568.  
  1569.  
  1570. /* Decode GFX Roms - Compensate for the address lines scrambling */
  1571.  
  1572.     /*    Sprites - decrypting the sprites nearly KILLED ME!
  1573.         It's been the main cause of the delay of this driver ...
  1574.         I hope you'll appreciate this effort!    */
  1575.  
  1576.     /* let's swap even and odd *pixels* of the sprites */
  1577.     RAM = memory_region(REGION_GFX1);
  1578.     for (i = 0; i < memory_region_length(REGION_GFX1); i ++)
  1579.     {
  1580.         int x = RAM[i];
  1581.         /* TODO: could be wrong, colors have to be fixed.       */
  1582.         /* The only certain thing is that 87 must convert to f0 */
  1583.         /* otherwise stray lines appear, made of pens 7 & 8     */
  1584.         x = ((x & 0x07) << 5) | ((x & 0xf8) >> 3);
  1585.         RAM[i] = x;
  1586.     }
  1587.  
  1588.     BITSWAP(memory_region(REGION_GFX1), memory_region_length(REGION_GFX1),
  1589.             0,1,20,19,18,17,14,9,16,6,4,7,8,15,10,11,13,5,12,3,2)
  1590.  
  1591.     /* Now we can unpack each nibble of the sprites into a pixel (one byte) */
  1592.     wecleman_unpack_sprites();
  1593.  
  1594.  
  1595.  
  1596.     /* Bg & Fg & Txt */
  1597.     BITSWAP(memory_region(REGION_GFX2), memory_region_length(REGION_GFX2),
  1598.             20,19,18,17,16,15,12,7,14,4,2,5,6,13,8,9,11,3,10,1,0);
  1599.  
  1600.  
  1601.  
  1602.     /* Road */
  1603.     BITSWAP(memory_region(REGION_GFX3), memory_region_length(REGION_GFX3),
  1604.             20,19,18,17,16,15,14,7,12,4,2,5,6,13,8,9,11,3,10,1,0);
  1605. }
  1606.  
  1607.  
  1608.  
  1609.  
  1610.  
  1611. /***************************************************************************
  1612.                                 Hot Chase
  1613. ***************************************************************************/
  1614.  
  1615.  
  1616. ROM_START( hotchase )
  1617.     ROM_REGION( 0x40000, REGION_CPU1 )            /* Main Code */
  1618.     ROM_LOAD_EVEN( "763k05", 0x000000, 0x010000, 0xf34fef0b )
  1619.     ROM_LOAD_ODD ( "763k04", 0x000000, 0x010000, 0x60f73178 )
  1620.     ROM_LOAD_EVEN( "763k03", 0x020000, 0x010000, 0x28e3a444 )
  1621.     ROM_LOAD_ODD ( "763k02", 0x020000, 0x010000, 0x9510f961 )
  1622.  
  1623.     ROM_REGION( 0x20000, REGION_CPU2 )            /* Sub Code */
  1624.     ROM_LOAD_EVEN( "763k07", 0x000000, 0x010000, 0xae12fa90 )
  1625.     ROM_LOAD_ODD ( "763k06", 0x000000, 0x010000, 0xb77e0c07 )
  1626.  
  1627.     ROM_REGION( 0x10000, REGION_CPU3 )            /* Sound Code */
  1628.     ROM_LOAD( "763f01", 0x8000, 0x8000, 0x4fddd061 )
  1629.  
  1630.     ROM_REGION( 0x300000 * 2, REGION_GFX1 )    /* x2, do not dispose */
  1631.     ROM_LOAD( "763e17", 0x000000, 0x080000, 0x8db4e0aa )    // zooming sprites
  1632.     ROM_LOAD( "763e20", 0x080000, 0x080000, 0xa22c6fce )
  1633.     ROM_LOAD( "763e18", 0x100000, 0x080000, 0x50920d01 )
  1634.     ROM_LOAD( "763e21", 0x180000, 0x080000, 0x77e0e93e )
  1635.     ROM_LOAD( "763e19", 0x200000, 0x080000, 0xa2622e56 )
  1636.     ROM_LOAD( "763e22", 0x280000, 0x080000, 0x967c49d1 )
  1637.  
  1638.     ROM_REGION( 0x20000, REGION_GFX2 )
  1639.     ROM_LOAD( "763e14", 0x000000, 0x020000, 0x60392aa1 )    // bg
  1640.  
  1641.     ROM_REGION( 0x10000, REGION_GFX3 )
  1642.     ROM_LOAD( "763a13", 0x000000, 0x010000, 0x8bed8e0d )    // fg (patched)
  1643.  
  1644.     ROM_REGION( 0x20000, REGION_GFX4 | REGIONFLAG_DISPOSE )
  1645.     ROM_LOAD( "763e15", 0x000000, 0x020000, 0x7110aa43 )    // road
  1646.  
  1647.     ROM_REGION( 0x40000, REGION_SOUND1 )        /* Samples */
  1648.     ROM_LOAD( "763e11", 0x000000, 0x040000, 0x9d99a5a7 )    // 2 banks
  1649.  
  1650.     ROM_REGION( 0x40000, REGION_SOUND2 )        /* Samples */
  1651.     ROM_LOAD( "763e10", 0x000000, 0x040000, 0xca409210 )    // 2 banks
  1652.  
  1653.     ROM_REGION( 0x100000, REGION_SOUND3 )        /* Samples */
  1654.     ROM_LOAD( "763e08", 0x000000, 0x080000, 0x054a9a63 )    // 4 banks
  1655.     ROM_LOAD( "763e09", 0x080000, 0x080000, 0xc39857db )    // 4 banks
  1656.  
  1657.     ROM_REGION( 0x08000, REGION_USER1 )
  1658.     ROM_LOAD( "763a12", 0x000000, 0x008000, 0x05f1e553 )    // ??
  1659. ROM_END
  1660.  
  1661.  
  1662.  
  1663.  
  1664. /*    Important: you must leave extra space when listing sprite ROMs
  1665.     in a ROM module definition.  This routine unpacks each sprite nibble
  1666.     into a byte, doubling the memory consumption. */
  1667.  
  1668. void hotchase_sprite_decode( int num_banks, int bank_size )
  1669. {
  1670.     unsigned char *base, *temp;
  1671.     int i;
  1672.  
  1673.     base = memory_region(REGION_GFX1);    // sprites
  1674.     temp = malloc( bank_size );
  1675.     if( !temp ) return;
  1676.  
  1677.     for( i = num_banks; i >0; i-- ){
  1678.         unsigned char *finish    = base + 2*bank_size*i;
  1679.         unsigned char *dest     = finish - 2*bank_size;
  1680.  
  1681.         unsigned char *p1 = temp;
  1682.         unsigned char *p2 = temp+bank_size/2;
  1683.  
  1684.         unsigned char data;
  1685.  
  1686.         memcpy (temp, base+bank_size*(i-1), bank_size);
  1687.  
  1688.         do {
  1689.             data = *p1++;
  1690.             if( (data&0xf0) == 0xf0 ) data &= 0x0f;
  1691.             if( (data&0x0f) == 0x0f ) data &= 0xf0;
  1692.             *dest++ = data >> 4;
  1693.             *dest++ = data & 0xF;
  1694.             data = *p1++;
  1695.             if( (data&0xf0) == 0xf0 ) data &= 0x0f;
  1696.             if( (data&0x0f) == 0x0f ) data &= 0xf0;
  1697.             *dest++ = data >> 4;
  1698.             *dest++ = data & 0xF;
  1699.  
  1700.  
  1701.             data = *p2++;
  1702.             if( (data&0xf0) == 0xf0 ) data &= 0x0f;
  1703.             if( (data&0x0f) == 0x0f ) data &= 0xf0;
  1704.             *dest++ = data >> 4;
  1705.             *dest++ = data & 0xF;
  1706.             data = *p2++;
  1707.             if( (data&0xf0) == 0xf0 ) data &= 0x0f;
  1708.             if( (data&0x0f) == 0x0f ) data &= 0xf0;
  1709.             *dest++ = data >> 4;
  1710.             *dest++ = data & 0xF;
  1711.         } while( dest<finish );
  1712.     }
  1713.     free( temp );
  1714. }
  1715.  
  1716.  
  1717.  
  1718.  
  1719. /* Unpack sprites data and do some patching */
  1720. void init_hotchase(void)
  1721. {
  1722.     unsigned char *RAM;
  1723.     int i;
  1724.  
  1725. /* Optional code patches */
  1726.  
  1727.     /* Main CPU patches */
  1728.     RAM = memory_region(REGION_CPU1);
  1729.     WRITE_WORD (&RAM[0x1140],0x0015);    WRITE_WORD (&RAM[0x195c],0x601A);    // faster self test
  1730.  
  1731.     /* Sub CPU patches */
  1732.     RAM = memory_region(REGION_CPU2);
  1733.  
  1734.     /* Sound CPU patches */
  1735.     RAM = memory_region(REGION_CPU3);
  1736.  
  1737.  
  1738. /* Decode GFX Roms */
  1739.  
  1740.     /* Let's swap even and odd bytes of the sprites gfx roms */
  1741.     RAM = memory_region(REGION_GFX1);
  1742.     for (i = 0; i < memory_region_length(REGION_GFX1); i += 2)
  1743.     {
  1744.         int x = RAM[i];
  1745.         RAM[i] = RAM[i+1];
  1746.         RAM[i+1] = x;
  1747.     }
  1748.  
  1749.     /* Now we can unpack each nibble of the sprites into a pixel (one byte) */
  1750.     hotchase_sprite_decode(3,0x80000*2);    // num banks, bank len
  1751.  
  1752.  
  1753.     /* Let's copy the second half of the fg layer gfx (charset) over the first */
  1754.     RAM = memory_region(REGION_GFX3);
  1755.     memcpy(&RAM[0], &RAM[0x10000/2], 0x10000/2);
  1756.  
  1757. }
  1758.  
  1759.  
  1760.  
  1761. /***************************************************************************
  1762.  
  1763.                                 Game driver(s)
  1764.  
  1765. ***************************************************************************/
  1766.  
  1767. GAMEX(1986, wecleman, 0, wecleman, wecleman, wecleman, ROT0, "Konami", "WEC Le Mans 24", GAME_WRONG_COLORS )
  1768. GAME( 1988, hotchase, 0, hotchase, hotchase, hotchase, ROT0, "Konami", "Hot Chase" )
  1769.